#include "MainMenu.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

#if INSTALANDO
#define PATH_RES PATH_RESOURCES
#else
#define PATH_RES "../Resources/"
#endif

MainMenu::MainMenu(string yamlfile) {
	log_menu.open(LOG_MENU);
	log_menu << "Abierto log Menu\n" << flush;
	
	cliente = NULL;
	servidor = NULL;
	string path_res = PATH_RES;
	musica = Mix_LoadMUS((path_res+"All_star.ogg").c_str());
	if (musica == NULL) cout << "musica es NULL" << endl << flush;
	cuadroActual = 0;
	animacionActual = 0;
	
	mensaje = "";
	status = OK;

	parsear(yamlfile, juego);

}

MainMenu::~MainMenu () {
}

Cliente* MainMenu::getCliente() {
	return cliente;
}

Servidor* MainMenu::getServidor() {
	return servidor;
}

int MainMenu::getAnchoNivel() {
	return ancho_nivel;
}

int MainMenu::getAltoNivel() {
	return alto_nivel;
}

Mix_Music* MainMenu::getMusica() {
	return musica;
}	

void MainMenu::setMusica( Mix_Music* mus){
	musica = mus;
}

unsigned int MainMenu::getModo() {
		return modo;
}

pid_t MainMenu::getPidServidor() {
	return pid_servidor;
}
	
pid_t MainMenu::getPidCliente() {
	return pid_cliente;
}

string MainMenu::getSonido() {
	string nivel;
	if ( modo == MULTI_PLAYER ) nivel = menu->getServidorNivel();
	if ( modo == SINGLE_PLAYER ) nivel = menu->getSingleNivel();

	
	for ( unsigned int i=0; i<(juego.niveles).size();i++ ) {
       if ( juego.niveles[i].nombre == nivel ) {
             return(juego.niveles[i].sonido).c_str();
         }
    }
    
    return "";
}
		
void MainMenu::setModo(unsigned int i) {
	modo = i;
}

void MainMenu::setAnchoNivel(int ancho) {
	ancho_nivel=ancho;
}

void MainMenu::setAltoNivel(int alto) {
	alto_nivel=alto;
}

int MainMenu::cargarMenuInicial(SDL_Surface* pantalla) {
	
	SDL_Event event;
	string path_res = PATH_RES;
	SDL_Surface* fondo = cargar_imagen((path_res+"fondo.bmp").c_str());
	fondo = ajustar_imagen(fondo, 650, 500);
	
	TTF_Font* font54 = TTF_OpenFont((path_res+"fontMario.ttf").c_str(), 54 );
	SDL_Color white = { 255, 255, 255 };
    SDL_Surface* mensaje = TTF_RenderText_Solid( font54, "BIENVENIDO!", white );    //OJO! HARDCODE
	
	Boton* boton_multi;
	Boton* boton_single;
	boton_multi = new Boton( 320, 250, 150, 30, "Multi Player", 0, 0);
	boton_single = new Boton( 120, 250, 150, 30, "Single Player", 0, 0);
	insertar_imagen( 0, 0, fondo, pantalla );
	insertar_imagen( 145, 10, mensaje, pantalla );    	
	boton_multi->dibujarBoton(pantalla);
	boton_single->dibujarBoton(pantalla);
	
	SDL_Flip(pantalla);
	bool quit = false;
	
	 while( quit == false )
    {
        if ( SDL_PollEvent( &event ) ) {
		
			if ((event.type == SDL_MOUSEBUTTONDOWN) || (event.type == SDL_MOUSEBUTTONUP)) {
            
                if ( boton_multi->handleBoton(event, 0, 0 ) == true ) {
					SDL_Flip(pantalla);
					setModo(MULTI_PLAYER);
					return MULTI_PLAYER;
				}
					
				if ( boton_single->handleBoton(event, 0, 0 ) == true ) {
					SDL_Flip(pantalla);
					setModo(SINGLE_PLAYER);
					return SINGLE_PLAYER;
				}	
			}
				
			if( event.type == SDL_QUIT )
            {
				if (servidor) delete servidor;
				if (cliente) delete cliente;
				//kill(pid_cliente, SIGKILL);
				kill(pid_servidor, SIGKILL);
            	exit(0);
            }
				 
		}
		
	}
	return SINGLE_PLAYER;
}

Menu* MainMenu::cargarMenuMulti(string host, string port, vector<string> v_niveles, int cantidad){

	vector<Mensaje*> v_mensajes;
	vector<Boton*> v_botones;
	vector<InputBox*> v_inputs;
	vector<MenuDeslizante*> v_deslizantes;
	vector<Solapa*> v_solapas;
	vector<string> v_aux;

	Mensaje* mensaje;
	InputBox* input;
	Boton* boton;
	MenuDeslizante* deslizante;
	Solapa* solapa;

	Menu* menu;

/***************** CLIENTE **********************/

	mensaje = new Mensaje("Host:", 50, 50, 0);
	v_mensajes.push_back(mensaje);

	mensaje = new Mensaje("Puerto:", 50, 100, 0);
	v_mensajes.push_back(mensaje);

	mensaje = new Mensaje("Elija personaje:", 50, 25, 1);
	v_mensajes.push_back(mensaje);

	input = new InputBox(120, 50, 300, 20, 0, 1, host);
	v_inputs.push_back(input);

	input = new InputBox(120, 100, 300, 20, 0, 2, port);
	v_inputs.push_back(input);

	boton = new Boton( 350, 200, 100, 25, "Conectar", 0, 1);
	v_botones.push_back(boton);

	boton = new Boton( 350, 200, 100, 25, "Jugar", 1, 2);
	v_botones.push_back(boton);
	
	deslizante = new MenuDeslizante(v_aux, 50, 75, 200, 100, 1 );
	v_deslizantes.push_back(deslizante);

	solapa = new Solapa( "Cliente", v_mensajes, v_inputs, v_botones, v_deslizantes );
	v_solapas.push_back(solapa);

	v_mensajes.clear();
	v_mensajes.clear();
	v_inputs.clear();
	v_botones.clear();
	v_deslizantes.clear();
	v_aux.clear();

/***************** SERVIDOR **********************/

	mensaje = new Mensaje("Elija Nivel:", 50, 25, 0);
	v_mensajes.push_back(mensaje);

	mensaje = new Mensaje("Cantidad de Jugadores:", 50, 125, 0);
	v_mensajes.push_back(mensaje);
	
	deslizante = new MenuDeslizante(v_niveles, 50, 50, 200, 50, 0 );
	v_deslizantes.push_back(deslizante);
	
	for (int i=0; i < cantidad; i++ ) {
		int suma = i + 1;
		std::string s_cantidad;
		std::stringstream out;
		out << suma;
		s_cantidad = out.str();

		v_aux.push_back(s_cantidad);
	}

	deslizante = new MenuDeslizante(v_aux, 50, 150, 200, 50, 0 );
	v_deslizantes.push_back(deslizante);


	mensaje = new Mensaje("Puerto:", 50, 220, 0);
	v_mensajes.push_back(mensaje);

	input = new InputBox(120, 220, 100, 20, 0, 3, port);
	v_inputs.push_back(input);

	boton = new Boton( 300, 200, 100, 25, "Crear", 0, 3);
	v_botones.push_back(boton);

	solapa = new Solapa( "Servidor", v_mensajes, v_inputs, v_botones, v_deslizantes );
	v_solapas.push_back(solapa);

	v_aux.clear();
	v_mensajes.clear();
	v_inputs.clear();
	v_botones.clear();
	v_deslizantes.clear();
	v_aux.clear();

	/***************** MENU FINAL **********************/
	
	string path_res = PATH_RES;
	menu = new Menu(path_res+"fondo.bmp", 650, 500, v_solapas );
	
	log_menu << "Se cargaron los elementos del Menu\n" << flush;

	return menu;
}

Menu* MainMenu::cargarMenuSingle(vector<string> v_niveles) {
vector<Mensaje*> v_mensajes;
	vector<Boton*> v_botones;
	vector<InputBox*> v_inputs;
	vector<MenuDeslizante*> v_deslizantes;
	vector<Solapa*> v_solapas;
	vector<string> v_aux;

	Mensaje* mensaje;
	Boton* boton;
	MenuDeslizante* deslizante;
	Solapa* solapa;

	Menu* menu;

/***************** CLIENTE **********************/

	mensaje = new Mensaje("Elija nivel:", 50, 25, 0);
	v_mensajes.push_back(mensaje);
	
	mensaje = new Mensaje("Elija Personaje:", 50, 25, 1);
	v_mensajes.push_back(mensaje);

	boton = new Boton( 350, 200, 100, 25, "Elegir", 0, 4);
	v_botones.push_back(boton);

	boton = new Boton( 350, 200, 100, 25, "Jugar", 1, 5);
	v_botones.push_back(boton);
	
	deslizante = new MenuDeslizante(v_niveles, 50, 75, 200, 100, 0 );
	v_deslizantes.push_back(deslizante);
	
	deslizante = new MenuDeslizante(v_aux, 50, 75, 200, 100, 1 );
	v_deslizantes.push_back(deslizante);

	solapa = new Solapa( "Cliente", v_mensajes, v_inputs, v_botones, v_deslizantes );
	v_solapas.push_back(solapa);

	v_mensajes.clear();
	v_mensajes.clear();
	v_inputs.clear();
	v_botones.clear();
	v_deslizantes.clear();
	v_aux.clear();

/***************** MENU FINAL **********************/

	string path_res = PATH_RES;
	menu = new Menu(path_res+"fondo.bmp", 650, 500, v_solapas );

	return menu;
}

void MainMenu::DecodificarInfoImagenes(string mensaje) {
	
	infoImagenes.clear();
	
	unsigned int cantidadImagenes = count(mensaje.begin(), mensaje.end(), '#');
	
	while (cantidadImagenes != 0) {
		
		infoImagen_t infoImagen;
		
		infoImagen.idImagen = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoImagen.ruta = mensaje.substr(0, mensaje.find_first_of(';'));
		mensaje.erase(0, mensaje.find_first_of(';')+1);;

		infoImagen.anchoCuadro = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoImagen.altoCuadro = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoImagen.cantCuadros = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoImagen.angulo = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoImagen.espejar = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		mensaje.erase(0, mensaje.find_first_of("#")+1);
		
		infoImagenes.push_back(infoImagen);
		cantidadImagenes--;
	}
}

vector<infoImagen_t> MainMenu::getInfoImagenes() {
	
	return infoImagenes;
}

vector<InfoPersonaje*> MainMenu::getInfoPersonajes() {
	
	return infoPersonajes;
}

void MainMenu::DecodificarInfoSonidos(string mensaje) {
	
	infoSonidos.clear();
	
	unsigned int cantidadSonidos = count(mensaje.begin(), mensaje.end(), '#');
	
	while (cantidadSonidos != 0) {
		
		infoSonido_t infoSonido;
		
		infoSonido.idSonido = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	

		infoSonido.tipo = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);
		
		infoSonido.ruta = mensaje.substr(0, mensaje.find_first_of(';'));
		mensaje.erase(0, mensaje.find_first_of(';')+1);
		
		mensaje.erase(0, mensaje.find_first_of("#")+1);
		
		infoSonidos.push_back(infoSonido);
		cantidadSonidos--;
	}
}

vector<infoSonido_t> MainMenu::getInfoSonidos() {
	
	return infoSonidos;
}

Menu* MainMenu::getMenu() {
	
	return menu;
}

void MainMenu::DecodificarPersonajesHabilitados(string mensaje) {
	
	infoPersonajes.clear();
	
	unsigned int cantidadPersonajes = count(mensaje.begin(), mensaje.end(), '#');
	while (cantidadPersonajes != 0) {
		InfoPersonaje* infoPersonaje = new InfoPersonaje();
		
		infoPersonaje->id = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoPersonaje->nombre = mensaje.substr(0, mensaje.find_first_of(';'));
		mensaje.erase(0, mensaje.find_first_of(';')+1);
		
		infoPersonaje->ancho = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoPersonaje->alto = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoPersonaje->velocidad = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoPersonaje->salto = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);	
		
		infoPersonaje->margenScroll=atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
		mensaje.erase(0, mensaje.find_first_of(';')+1);

		for (unsigned int j=0; j<EstadoBasico::acciones.size(); j++) {
			InfoImagen* infoAnimacion = new InfoImagen();
			infoAnimacion->archivo = mensaje.substr(0, mensaje.find_first_of(";"));
			mensaje.erase(0, mensaje.find_first_of(';')+1);	
			
			infoAnimacion->cuadros = atoi(mensaje.substr(0, mensaje.find_first_of(';')).c_str());
			mensaje.erase(0, mensaje.find_first_of(';')+1);	
			
			infoPersonaje->animaciones.push_back(infoAnimacion);
		}
		
		mensaje.erase(0, mensaje.find_first_of("#")+1);
		
		infoPersonajes.push_back(infoPersonaje);
		
		cantidadPersonajes--;
		
	}
}

string MainMenu::getNextMessage() {
	
	int len = 0;
	ioctl(cliente->getSocket(), FIONREAD, &len);
	if (len > 0) {
		string mensaje_aux;
		status = readSocket(cliente->getSocket(), &mensaje_aux, len);
		if (status == OK) mensaje += mensaje_aux;
	}
	
	string update = "";
	if (mensaje.find_first_of('>') != string::npos) {
		update = mensaje.substr(mensaje.find_first_of('<')+1, mensaje.find_first_of('>')-1);
		mensaje.erase(mensaje.find_first_of('<'), mensaje.find_first_of('>')+1);
	}
	return update;
}

void MainMenu::handleMenuBotones(SDL_Event event, Menu* menu, SDL_Surface* pantalla, Juego juego, bool* quit) {

	log_menu << "/************************************************/\n" << flush;
	log_menu << "/*             HANDLE MENU BOTONES              */\n" << flush;
	log_menu << "/************************************************/\n" << flush;

	vector<Boton*> v_botones = menu->getSolapas().at(menu->getSolapaActiva())->getBotones();
	int cant_elem = v_botones.size();
	
	for (int i=0; i < cant_elem; i++ ) {

		if (v_botones.at(i)->getPaso() == menu->getSolapas().at(menu->getSolapaActiva())->getPaso()) {

			if ( v_botones.at(i)->handleBoton(event, (menu->getSolapas().at(menu->getSolapaActiva())->getX()),
													  menu->getSolapas().at(menu->getSolapaActiva())->getY()
				                                  	  ) == true ) {


				if ( v_botones.at(i)->getId() == 1 ) {
					log_menu << "Click en conectar" << endl << flush;
					menu->setEstado(8);
					menu->DibujarBarraEstado();
					SDL_Flip(pantalla);
					
					string nivel_m = menu->getServidorNivel();
					
					for ( unsigned int i=0; i<(juego.niveles).size();i++ ) {
						if ( juego.niveles[i].nombre == nivel_m ) {
							cliente = new Cliente ();
							break;
						}
					}

					log_menu << "Se creo el cliente" << endl << flush;
					
					menu->setEstado(12);
					menu->DibujarBarraEstado();
					menu->getSolapas().at(0)->getBotones().at(0)->setEstado(0);
					SDL_Flip(pantalla);

					if ( cliente->Conectar(menu->getClienteIp(), menu->getClientePuerto())) {

						log_menu << "Conectado" << endl << flush;
						
						menu->getSolapas().at(0)->setPaso(1);
						menu->setEstado(1);

						log_menu << "En paso: Elegir personaje" << endl << flush;
						
						log_menu << "Leer socket: Mensaje que indica si hay vacantes para jugar" << endl << flush;
						string update = getNextMessage();
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							menu->setEstado(9);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							log_menu << "Sin conexion.  Vuelve al inicio del menu" << endl << flush;
							return;	
						}
						if (update == "No") {
							menu->setEstado(15);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;
						}
					
						log_menu << "Leer socket: Mensaje con las imagenes" << endl << flush;
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							menu->setEstado(9);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							log_menu << "Sin conexion.  Vuelve al inicio del menu" << endl << flush;
							return;	
						}
						log_menu << "Decodificando imagenes..." << endl << flush;
						DecodificarInfoImagenes(update);
						log_menu << "Las Imagenes han sido decodificadas" << endl << flush;
						
						log_menu << "Leer socket: Mensaje con los sonidos" << endl << flush;
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							menu->setEstado(9);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							log_menu << "Sin conexion.  Vuelve al inicio del menu" << endl << flush;
							return;	
						}
						log_menu << "Decodificando sonidos..." << endl << flush;
						DecodificarInfoSonidos(update);
						log_menu << "Los sonidos han sido decodificadss" << endl << flush;
						
						log_menu << "Leyendo alto y ancho nivel" << endl << flush;
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							menu->setEstado(9);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							log_menu << "Sin conexion.  Vuelve al inicio del menu" << endl << flush;
							return;	
						}
						int anchoNivel = atoi(update.substr(0, update.find_first_of(';')).c_str());				
						int altoNivel = atoi(update.substr(update.find_first_of(';')+1, update.find_first_of('#')).c_str());
						setAnchoNivel(anchoNivel);
						setAltoNivel(altoNivel);
					
						log_menu << "Decodificando personajes habilitados..." << endl << flush;
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							menu->setEstado(9);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							log_menu << "Sin conexion.  Vuelve al inicio del menu" << endl << flush;
							return;	
						}		
						if ( update == "<>" ) {
							menu->setEstado(11);
							menu->getSolapas().at(0)->setPaso(0);
							SDL_Flip(pantalla);
							delete cliente;
							cliente = NULL;
							return; 
						}	
						DecodificarPersonajesHabilitados(update);
						log_menu << "Los personajes habilitados han sido decodificados" << endl << flush;
					
						log_menu << "Asignando vector de descripciones y caracteristicas de los personajes" << endl << flush;

						menu->getSolapas().at(0)->getDeslizantes().at(0)->setPersonajes(infoPersonajes);
						
						vector<string> v_elem;				
						
						for (unsigned int i= 0; i < infoPersonajes.size(); i++) {
							v_elem.push_back(infoPersonajes.at(i)->nombre);
						}
						menu->getSolapas().at(0)->getDeslizantes().at(0)->setElementos(v_elem);				
						
						log_menu << "Creada la lista de personajes para el menu deslizante" << endl << flush;

						log_menu << "Cargando Animaciones..." << endl << flush;
						CargarAnimaciones(infoPersonajes);

						log_menu << "Animaciones cargadas" << endl << flush;
						infoPersonajeActual = infoPersonajes.at(0);
						
					} else {

					    log_menu << "No se pudo conectar al servidor" << endl << flush;
						delete cliente;
						cliente = NULL;
						menu->setEstado(2);
					}
	
				} else if ( (v_botones.at(i)->getId() == 2) ) {

				   	log_menu << "Click en Jugar" << endl << flush;
				   
					int var = menu->getSolapas().at(0)->getDeslizantes().at(0)->getSeleccionado();

				   string pregunta = Logger::intToString(infoPersonajes.at(var)->id) + "#";	
				   log_menu << "Escribir socket: Pregunta si el personaje esta habilitado" << endl << flush;
				   if ( writeSocket(cliente->getSocket(), pregunta) == SIN_CONEXION) {
						menu->setEstado(9);
						menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	

						log_menu << "Sin conexion.  Vuelve al inicio del menu" << endl << flush;
						return;							
					}

					log_menu << "Leer socket: Respuesta si el personaje esta habilitado" << endl << flush;
					string update = "";
					while (update == "" && status != SIN_CONEXION) {
						update = getNextMessage();
					}
					if (status == SIN_CONEXION) {
						menu->setEstado(9);
						menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
						log_menu << "Sin conexion.  Vuelve al inicio del menu" << endl << flush;
						return;	
					}
					if (update == "Si") {
						
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							menu->setEstado(9);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							log_menu << "Sin conexion.  Vuelve al inicio del menu" << endl << flush;
							return;	
						}
						if (update == "No") {
							menu->setEstado(15);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;
						}
						
						cliente->setPersonaje((rand()%(juego.pantalla.ancho))+1,(rand()%(juego.pantalla.alto)+1),infoPersonajes.at(var)->ancho,infoPersonajes.at(var)->alto,infoPersonajes.at(var)->margenScroll);
						*quit = true;

						 log_menu << "Personaje habilitado" << endl << flush;
					} else  {
						menu->setEstado(4);
						
						log_menu << "Personaje no habilitado" << endl << flush;
						log_menu << "Decodificando personajes habilitados..." << endl << flush;
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							menu->setEstado(9);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							log_menu << "Sin conexion.  Vuelve al inicio del menu" << endl << flush;
							return;	
						}
						if ( update == "<>" ) {
							menu->setEstado(11);
							menu->getSolapas().at(0)->setPaso(0);
							SDL_Flip(pantalla);
							delete cliente;
							cliente = NULL;
							return; 
						}	
					
						DecodificarPersonajesHabilitados(update);
						
						log_menu << "Los personajes habilitados han sido decodificados" << endl << flush;
						
						log_menu << "Asignando vector de descripciones y caracteristicas de los personajes" << endl << flush;
						menu->getSolapas().at(0)->getDeslizantes().at(0)->setPersonajes(infoPersonajes);
						vector<string> v_elem;
						
						for (unsigned int i= 0; i < infoPersonajes.size(); i++) {
							v_elem.push_back(infoPersonajes.at(i)->nombre);
						}
						menu->getSolapas().at(0)->getDeslizantes().at(0)->setElementos(v_elem);
						
						log_menu << "Creada la lista de personajes para el menu deslizante" << endl << flush;

						log_menu << "Cargando Animaciones..." << endl << flush;
						CargarAnimaciones(infoPersonajes);

						log_menu << "Animaciones cargadas" << endl << flush;
						infoPersonajeActual = infoPersonajes.at(0);
					}

					log_menu << "Borro listado de personajes habilitados" << endl << flush;

				} else if ( v_botones.at(i)->getId() == 3) {
					
					menu->setEstado(7);
					servidor = new Servidor(atoi((menu->getServidorPuerto()).c_str()), juego, menu->getServidorNivel(), menu->getServidorCantidadPersonajes());

					log_menu << "Se creo el servidor" << endl << flush;
					
					if (servidor->getBuscador()->getEstado() == NoAceptaConexiones ) {
						servidor = NULL;
						menu->setEstado(6);

					    log_menu << "El servidor no esta conectado" << endl << flush;
					}
					else {
						menu->setEstado(5);
						*quit = true;
						
						//MUSICA
						if( Mix_PlayingMusic() == 1 )
						{
							Mix_HaltMusic();

						}

						log_menu << "El servidor esta corriendo" << endl << flush;
					}

				} else if ( v_botones.at(i)->getId() == 4) {

					menu->setEstado(12);
					int puerto = 51000;

					while (true) {
						
						servidor = new Servidor(puerto, juego, menu->getSingleNivel(), 1);

						if (servidor->getBuscador()->getEstado() == NoAceptaConexiones ) {
							puerto++;
							servidor = NULL;
						} else {
							menu->getSolapas().at(0)->setPaso(1);
							break;
						}
					 }
					 
					 			
/*********************** BACKGROUND SERVIDOR **************************/

					pid_servidor = fork();
					if ( pid_servidor < 0 ) {
						exit(EXIT_FAILURE);
					} else if ( pid_servidor > 0 ) {

					} else if ( pid_servidor == 0 ) {

					    fclose(stdout);
						fclose(stderr);
						
						if( Mix_PlayingMusic() == 1 ) Mix_HaltMusic();
						servidor->Correr(0);
						delete servidor;
						servidor = NULL;
						exit(EXIT_SUCCESS);

					} 
/*********************** FOREGROUND CLIENTE ***************************/					
					pid_cliente = fork();
					if ( pid_cliente < 0 ) {
						exit(EXIT_FAILURE);
					} else if ( pid_cliente > 0 ) {
						if( Mix_PlayingMusic() == 0 ) {
							
							if( Mix_PlayMusic( musica, 1 ) == -1 ){
								cout<< "No se pudo iniciar musica ( Error: " << Mix_GetError() << ". )" << endl << flush;
							} 
						}


					string nivel_s = menu->getSingleNivel();
					for ( unsigned int i=0; i<(juego.niveles).size();i++ ) {
						if ( juego.niveles[i].nombre == nivel_s ) {
							cliente = new Cliente ();
							break;
						}
					}
		
					std::string s_puerto;
					std::stringstream out;
					out << puerto;
					s_puerto = out.str();

					sleep(1);
					if ( cliente->Conectar("localhost", s_puerto.c_str()) ) {
								
						menu->getSolapas().at(0)->setPaso(1);
						menu->setEstado(13);

							
						string update = getNextMessage();
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
							
						if (status == SIN_CONEXION) {
							delete servidor;
							servidor = NULL;
							kill(pid_servidor, SIGKILL);
							menu->setEstado(14);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;	
						}
						if (update == "No") {
							menu->setEstado(15);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;						
						}
						
							
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
							
						if (status == SIN_CONEXION) {
							delete servidor;
							servidor = NULL;
							kill(pid_servidor, SIGKILL);
							menu->setEstado(14);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;	
						}
	
						DecodificarInfoImagenes(update);
						
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							delete servidor;
							servidor = NULL;
							kill(pid_servidor, SIGKILL);
							menu->setEstado(14);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;
						}

						DecodificarInfoSonidos(update);

						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							delete servidor;
							servidor = NULL;
							kill(pid_servidor, SIGKILL);
							menu->setEstado(14);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;	
						}
						int anchoNivel = atoi(update.substr(0, update.find_first_of(';')).c_str());				
						int altoNivel = atoi(update.substr(update.find_first_of(';')+1, update.find_first_of('#')).c_str());
						setAnchoNivel(anchoNivel);
						setAltoNivel(altoNivel);
					
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							delete servidor;
							servidor = NULL;
							kill(pid_servidor, SIGKILL);
							menu->setEstado(14);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;	
						}
						if ( update == "<>" ) {
							menu->setEstado(11);
							menu->getSolapas().at(0)->setPaso(0);
							SDL_Flip(pantalla);
							delete cliente;
							cliente = NULL;
							return; 
						}	

						DecodificarPersonajesHabilitados(update);

						menu->getSolapas().at(0)->getDeslizantes().at(1)->setPersonajes(infoPersonajes);
					
						vector<string> v_elem;				
					    
						for (unsigned int i= 0; i < infoPersonajes.size(); i++) {
							v_elem.push_back(infoPersonajes.at(i)->nombre);
						}
						menu->getSolapas().at(0)->getDeslizantes().at(1)->setElementos(v_elem);				

						CargarAnimaciones(infoPersonajes);

						infoPersonajeActual = infoPersonajes.at(0);
					    break;
					  } else {
						delete servidor;
						servidor = NULL;
						kill(pid_servidor, SIGKILL);
						menu->setEstado(14);
						menu->getSolapas().at(0)->setPaso(0);
						return;
					  }

					} else if ( pid_cliente == 0 ) {
						exit(0);
					}
					
				
				} else if ( v_botones.at(i)->getId() == 5) {

				   int var = menu->getSolapas().at(0)->getDeslizantes().at(1)->getSeleccionado();
				   string pregunta = Logger::intToString(infoPersonajes.at(var)->id) + "#";	
				
				   if ( writeSocket(cliente->getSocket(), pregunta) == SIN_CONEXION) {
						menu->setEstado(9);
						menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	

						return;							
					}
					string update = "";
					while (update == "" && status != SIN_CONEXION) {
						update = getNextMessage();
					}
					if (status == SIN_CONEXION) {
						menu->setEstado(9);
						menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
						return;	
					}

					if (update == "Si") {
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							menu->setEstado(9);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;	
						}
						if (update == "No") {
							menu->setEstado(15);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;
						}

						cliente->setPersonaje((rand()%(juego.pantalla.ancho))+1,(rand()%(juego.pantalla.alto)+1),infoPersonajes.at(var)->ancho,infoPersonajes.at(var)->alto,infoPersonajes.at(var)->margenScroll);
						*quit = true;
													
					} else  {
						menu->setEstado(4);
						
						update = "";
						while (update == "" && status != SIN_CONEXION) {
							update = getNextMessage();
						}
						if (status == SIN_CONEXION) {
							menu->setEstado(9);
							menu->getSolapas().at(menu->getSolapaActiva())->setPaso(0);	
							return;	
						}			
						if ( update == "<>" ) {
							menu->setEstado(11);
							menu->getSolapas().at(0)->setPaso(0);
							SDL_Flip(pantalla);
							delete cliente;
							cliente = NULL;
							return; 
						}	
					
						DecodificarPersonajesHabilitados(update);
						
						menu->getSolapas().at(0)->getDeslizantes().at(0)->setPersonajes(infoPersonajes);
						vector<string> v_elem;
						
						for (unsigned int i= 0; i < infoPersonajes.size(); i++) {
							v_elem.push_back(infoPersonajes.at(i)->nombre);
						}
						menu->getSolapas().at(0)->getDeslizantes().at(0)->setElementos(v_elem);
						

						CargarAnimaciones(infoPersonajes);

						infoPersonajeActual = infoPersonajes.at(0);
					}

					
				}

			}
		}
	}
		log_menu << "/************************************************/\n" << flush;

}

void MainMenu::Mostrar(SDL_Surface* pantalla)
{
	
	log_menu << "/************************************************/\n" << flush;
	log_menu << "/*                  MOSTRAR MENU                */\n" << flush;
	log_menu << "/************************************************/\n" << flush;

	SDL_Event event;
	
//MUSICA
	if( Mix_PlayingMusic() == 0 )
    {
          //Play the music
          if( Mix_PlayMusic( musica, -1 ) == -1 )
          {
             cout<< "No se pudo iniciar musica ( Error: " << Mix_GetError() << ". )" << endl << flush;
          } 
    }
    //If music is being played
    else
    {
          //If the music is paused
          if( Mix_PausedMusic() == 1 )
          {
                 //Resume the music
                 Mix_ResumeMusic();
          }
    }
	
    
    int x, y, ab_x, ab_y, ar_x, ar_y, s_x, s_y;

    string host, puerto;
    stringstream ss_host, ss_puerto;
    ss_host << juego.conexion.host;
    ss_puerto << juego.conexion.port;
    host = ss_host.str();
    puerto = ss_puerto.str();
    vector<string> v_niveles = parser_lista_niveles(juego);
    int cantidad_personajes = juego.tiposPersonaje.size();
    int modo;
    
    if ( cargarMenuInicial(pantalla) == MULTI_PLAYER ) {

		log_menu << "Llamado a cargar menu MultiPlayer\n" << flush;
		menu = cargarMenuMulti(host, puerto, v_niveles, cantidad_personajes);
		modo = MULTI_PLAYER;
	
	} else {
		log_menu << "Llamado a cargar menu Single Player\n" << flush;
		menu = cargarMenuSingle(v_niveles);
		modo = SINGLE_PLAYER;
		
	}
	

    bool quit = false;
    
    log_menu << "Llamado a dibujar fondo\n" << flush;
	menu->DibujarFondo(pantalla, modo);


    SDL_Flip( pantalla );
    
    
	log_menu << "Comienza while de eventos\n" << flush;
	
	Timer t_animacion;
	t_animacion.start();
	
	Uint32 lastUpdateTime = t_animacion.getTick();
	string lastUpdate = "";
	
    while( quit == false )
    {
			
        if ( SDL_PollEvent( &event ) ) {

        	if (event.type != SDL_MOUSEMOTION)
            {

            	menu->handleMenu(event);

            	if ((event.type == SDL_MOUSEBUTTONDOWN) || (event.type == SDL_MOUSEBUTTONUP)) {
            		 x = event.button.x;
                     y = event.button.y;
					//OJO! HARDCODES
					if (menu->getSolapaActiva() == 0) {
						if( ( x > 350 + (menu->getSolapas().at(0)->getX()) ) &&
							( x < 350 + (menu->getSolapas().at(0)->getX()) + 100 ) &&
							( y > 200 + (menu->getSolapas().at(0)->getY()) ) &&
							( y < 200 + menu->getSolapas().at(0)->getY() + 25 ) ) {

								if ( modo == MULTI_PLAYER ) {
									menu->setEstado(10);
								} else {
									menu->setEstado(12);
								}
								menu->DibujarBarraEstado();
								SDL_Flip(pantalla);
						}
					}

            		handleMenuBotones(event, menu, pantalla, juego, &quit);

				}
			
            	if( event.type == SDL_QUIT )
            	{	
					for (unsigned int i=0; i <  menu->getSolapas().size(); i++) {
						SDL_FreeSurface ( menu->getSolapas().at(i)->getFondo() );
					}

					SDL_FreeSurface(  menu->getFondo() );

					if (cliente) delete cliente;
					if (servidor) delete servidor;
					//kill(pid_cliente, SIGKILL);
					kill(pid_servidor, SIGKILL);
            		exit(0);
            		
            	}	
            	menu->DibujarFondo(pantalla, modo);
            	SDL_Flip( pantalla );

            }
	}
	
        if ( SDL_GetKeyState(NULL) [SDLK_UP] || SDL_GetKeyState(NULL) [SDLK_DOWN]) {
        	menu->handleMenu(event);

        	menu->DibujarFondo(pantalla, modo);

           	SDL_Flip( pantalla );
        }

       if (SDL_GetMouseState(&x, &y)&SDL_BUTTON(1) ) { 

            if (((menu->getSolapas().at(menu->getSolapaActiva())->getDeslizantes()).size()) > 0) {
				
            	for (unsigned int i=0; i < (menu->getSolapas().at(menu->getSolapaActiva())->getDeslizantes()).size(); i++ ) {
					
					if ((menu->getSolapas().at(menu->getSolapaActiva())->getDeslizantes()).at(i)->getPaso() == menu->getSolapas().at(menu->getSolapaActiva())->getPaso()) {
						
						ab_x = (menu->getSolapas().at(menu->getSolapaActiva())->getDeslizantes().at(i)->getAbajo()->getX());
						ab_y = (menu->getSolapas().at(menu->getSolapaActiva())->getDeslizantes().at(i)->getAbajo()->getY());
						ar_x = (menu->getSolapas().at(menu->getSolapaActiva())->getDeslizantes().at(i)->getArriba()->getX());
						ar_y = (menu->getSolapas().at(menu->getSolapaActiva())->getDeslizantes().at(i)->getArriba()->getY());
						s_x = (menu->getSolapas().at(menu->getSolapaActiva())->getX());
						s_y = (menu->getSolapas().at(menu->getSolapaActiva())->getY());


						if ( (( x >= s_x + ar_x) && (x <= s_x + ar_x + 15) && ((y >= s_y + ar_y) && (y <= s_y + ar_y + 15))) ||
							 (( x >= s_x + ab_x) && (x <= s_x + ab_x + 15) && ((y >= s_y + ab_y) && (y <= s_y + ab_y + 15)))) {

							menu->handleMenu(event);
							menu->DibujarFondo(pantalla, modo);

						}
					}
            	}
        	}

        }	
 	   
		if (menu->getSolapas().at(0)->getPaso() == 1) {
			if (t_animacion.getTick() - lastUpdateTime > TIEMPO_ENTRE_ANIMACIONES) {
				if ( modo == MULTI_PLAYER ) {
					MostrarAnimacion(700, 575, menu->getSolapas().at(0)->getDeslizantes().at(0)->getElementos().at(menu->getSolapas().at(0)->getDeslizantes().at(0)->getSeleccionado()), menu->getSolapas().at(0)->getDeslizantes().at(0)->getPersonajes(), pantalla);
				} else {
					MostrarAnimacion(700, 575, menu->getSolapas().at(0)->getDeslizantes().at(1)->getElementos().at(menu->getSolapas().at(0)->getDeslizantes().at(1)->getSeleccionado()), menu->getSolapas().at(0)->getDeslizantes().at(1)->getPersonajes(), pantalla);
				}
				SDL_Flip( pantalla );
				lastUpdateTime = t_animacion.getTick();

			}
		}

    }

 }

Juego MainMenu::getJuego() {
	
	return juego;
}

void MainMenu::CargarAnimaciones(vector<InfoPersonaje*> infoPersonajes) {
	unsigned int i, j;

	for (i=0; i < infoPersonajes.size(); i++) {
		for (j=0; j < infoPersonajes.at(i)->animaciones.size(); j++) {
			infoPersonajes.at(i)->animaciones.at(j)->imagen = cargar_imagen(PATH_SINCRONIZACION_CLIENTE + infoPersonajes.at(i)->animaciones.at(j)->archivo);
			infoPersonajes.at(i)->animaciones.at(j)->imagen = ajustar_imagen(infoPersonajes.at(i)->animaciones.at(j)->imagen, infoPersonajes.at(i)->ancho*infoPersonajes.at(i)->animaciones.at(j)->cuadros, infoPersonajes.at(i)->alto);
		}
		infoPersonajes.at(i)->clip = new SDL_Rect();
		infoPersonajes.at(i)->clip->h = infoPersonajes.at(i)->alto;
		infoPersonajes.at(i)->clip->w = infoPersonajes.at(i)->ancho;
		infoPersonajes.at(i)->clip->x = 0;
		infoPersonajes.at(i)->clip->y = 0;
	}
}

void MainMenu::MostrarAnimacion(int x, int y, string personaje, vector<InfoPersonaje*> infoPersonajes, SDL_Surface* pantalla) {
	unsigned int i;
    
	SDL_Surface* borde = SDL_CreateRGBSurface(0, 100, 115 , 32, 0, 0, 0, 0 );
	SDL_FillRect(borde, NULL, SDL_MapRGB(borde->format, 0, 0, 0));
	SDL_Surface* box = SDL_CreateRGBSurface(0, 98, 113 , 32, 0, 0, 0, 0 );
	SDL_FillRect(box, NULL, SDL_MapRGB(box->format, 255, 255, 255));

	insertar_imagen( 370, 220, borde, pantalla);
	insertar_imagen( 371, 221, box, pantalla);

	SDL_FreeSurface(borde);
	SDL_FreeSurface(box);

	if (personaje != infoPersonajeActual->nombre) {
		for (i=0; i < infoPersonajes.size(); i++) {
			if (personaje == infoPersonajes.at(i)->nombre)
				infoPersonajeActual = infoPersonajes.at(i);
		}
		cuadroActual = 0;
		animacionActual = 0;
	}

	else {
		int anim_size = infoPersonajeActual->animaciones.size();
		if (animacionActual >= anim_size ) {
			animacionActual = 0;
			cuadroActual = 0;
		}
		infoPersonajeActual->clip->x = cuadroActual*infoPersonajeActual->ancho;

		insertar_imagen(420-infoPersonajeActual->ancho/2, 225+110-infoPersonajeActual->alto, infoPersonajeActual->animaciones.at(animacionActual)->imagen, pantalla, infoPersonajeActual->clip);
		cuadroActual++;
		if (cuadroActual >= infoPersonajeActual->animaciones.at(animacionActual)->cuadros) {
			animacionActual++;
			cuadroActual = 0;
		}
	}
}
